import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';

function Square(props) {
    return (<button className='square' style={{ color: props.highlight ? 'red' : '' }} onClick={props.onClick}>{props.value}</button>)
}

class Board extends React.Component {
    constructor(props) {
        super(props);
        this.state = { squares: Array(9).fill(null), xIsNext: true, line: null }
    }

    renderSquare(i) {
        return <Square highlight={this.props.line?.includes(i)} key={i} value={this.props.squares[i]} onClick={() => this.props.onClick(i)} />;
    }

    render() {
        let index = 0
        // 3.使用两个循环来渲染出棋盘的格子，而不是在代码里写死（hardcode）。
        return (
            <div>
                {[1, 2, 3].map(i => (
                    <div key={i} className='board-row'>
                        {Array(3).fill(null).map(() => this.renderSquare(index++))}
                    </div>
                ))}
            </div>);
    }
}

class Game extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            history: [{ squares: Array(9).fill(null), index: null }],
            stepNumber: 0,
            xIsNext: true,
            historyIsDesc: false
        }
    }

    handleClick(i) {
        const history = this.state.history.slice(0, this.state.stepNumber + 1);
        const current = history[history.length - 1]
        const squares = current.squares.slice()
        if (calculateWinner(squares).winner || squares[i]) {
            return
        }
        squares[i] = this.state.xIsNext ? 'X' : 'O'
        // 1.在游戏历史记录列表显示每一步棋的坐标，格式为 (列号, 行号)。
        let row = i + 1;
        let cell = 1;
        while (row > 3) {
            row -= 3;
            cell++;
        }

        this.setState({
            history: history.concat([{ squares, index: { row, cell } }]),
            stepNumber: history.length,
            xIsNext: !this.state.xIsNext
        })
    }

    changeHistoryOrderBy() {
        this.setState((state) => ({ ...state, historyIsDesc: !state.historyIsDesc }))
    }

    jumpTo(stepNumber) {
        this.setState({
            stepNumber, xIsNext: (stepNumber % 2) === 0
        })
    }

    render() {
        const history = this.state.history;
        const current = history[this.state.stepNumber];
        const { winner, line } = calculateWinner(current.squares);
        let historyIsDesc = this.state.historyIsDesc;

        const moves = history.map((step, move) => {
            // console.log({ '步数': move, '记录': step.squares, '坐标': step.index, '是否选中': this.state.stepNumber == move })

            const desc = move ? `Go to move #${move} (${step.index.row},${step.index.cell})` : 'Go to game start';
            return (
                <li key={move}>
                    {/* 2.在历史记录列表中加粗显示当前选择的项目。 */}
                    <button style={{ fontWeight: this.state.stepNumber === move ? 'bold' : '' }} onClick={() => this.jumpTo(move)}>{desc}</button>
                </li>
            )
        })

        let status;
        if (winner) {
            status = 'Winner: ' + winner;
        } else {
            // 6.当无人获胜时，显示一个平局的消息。
            // console.log({ 'this.state.stepNumber': this.state.stepNumber })
            if (this.state.stepNumber < 9) {
                status = 'Next player: ' + (this.state.xIsNext ? 'X' : 'O');
            } else {
                status = 'Draw!';
            }
        }


        return (
            <div className="game">
                <div className="game-board">
                    <Board line={line} squares={current.squares} onClick={(i) => this.handleClick(i)} />
                </div>
                <div className="game-info">
                    <div>{status}</div>
                    {/* 4.添加一个可以升序或降序显示历史记录的按钮。 */}
                    <button onClick={() => this.changeHistoryOrderBy()}>{`切换为${historyIsDesc ? '升' : '降'}序显示历史记录`}</button>
                    <ol>{historyIsDesc ? moves.reverse() : moves}</ol>
                </div>
            </div>
        );
    }
}

// ========================================

ReactDOM.render(
    <Game />,
    document.getElementById('root')
);


function calculateWinner(squares) {
    const lines = [
        [0, 1, 2],
        [3, 4, 5],
        [6, 7, 8],
        [0, 3, 6],
        [1, 4, 7],
        [2, 5, 8],
        [0, 4, 8],
        [2, 4, 6],
    ];
    for (let i = 0; i < lines.length; i++) {
        const [a, b, c] = lines[i];
        // console.log([a, b, c])
        // console.log({ 'squares[a]': squares[a], 'squares[b]': squares[b], 'squares[c]': squares[c] })
        if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
            // 5.每当有人获胜时，高亮显示连成一线的 3 颗棋子。
            return { winner: squares[a], line: [a, b, c] };
        }
    }
    return {};
}